package com.yonyougov.devops.cruxcisupport.backupuser;

import com.yonyougov.devops.cruxcisupport.backupuser.dto.IssuedTestRequestDto;
import com.yonyougov.devops.cruxcisupport.backupuser.dto.ProcessPermissionsDto;
import com.yonyougov.devops.cruxcisupport.backupuser.vo.BackupUserVo;
import com.yonyougov.devops.cruxcisupport.commitcontext.CommitContextService;
import com.yonyougov.devops.cruxcisupport.commitcontext.vo.CommitContextInfoVo;
import com.yonyougov.devops.cruxcisupport.committest.CommitTestDao;
import com.yonyougov.devops.cruxcisupport.committest.CommitTestEntity;
import com.yonyougov.devops.cruxcisupport.committrace.CommitTraceDao;
import com.yonyougov.devops.cruxcisupport.committrace.CommitTraceEntity;
import com.yonyougov.devops.cruxcisupport.component.UserStore;
import com.yonyougov.devops.cruxcisupport.enums.TestStatusEnum;
import com.yonyougov.devops.cruxcisupport.user.UserDao;
import com.yonyougov.devops.cruxcisupport.user.UserEntity;
import com.yonyougov.devops.cruxcisupport.user.UserService;
import com.yonyougov.devops.cruxcisupport.util.CruxDevOpsIdGenerator;
import com.yonyougov.devops.cruxcisupport.util.MailUtils;
import com.yonyougov.devops.fwc.core.dao.BaseDao;
import com.yonyougov.devops.fwc.core.entity.Pagination;
import com.yonyougov.devops.fwc.core.service.impl.BaseServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigInteger;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 备用测试人员 表服务实现
 */
@Service
public class BackupTestUserServiceImpl extends BaseServiceImpl<BackupTestUserEntity, BigInteger> implements BackupTestUserService {
    private BackupTestUserDao backupTestUserDao;
    private UserStore userStore;
    private CommitTraceDao commitTraceDao;
    private UserDao userDao;
    private MailUtils mailUtils;
    private CommitTestDao commitTestDao;
    private CommitContextService commitContextService;
    @Autowired
    private BackupTestUserService backupTestUserService;
    @Autowired
    private UserService userService;
    @Value("${mail.fromMail.sender}")
    private String FROM;

    public BackupTestUserServiceImpl(BackupTestUserDao backupTestUserDao, UserStore userStore,
                                     CommitTraceDao commitTraceDao, UserDao userDao,
                                     MailUtils mailUtils, CommitTestDao commitTestDao,
                                     CommitContextService commitContextService) {
        this.backupTestUserDao = backupTestUserDao;
        this.userStore = userStore;
        this.commitTraceDao = commitTraceDao;
        this.userDao = userDao;
        this.mailUtils = mailUtils;
        this.commitTestDao = commitTestDao;
        this.commitContextService = commitContextService;
    }

    @Override
    public BaseDao<BackupTestUserEntity, BigInteger> getDao() {
        return backupTestUserDao;
    }

    //<!--用户自定义代码开始-->

    /**
     * 转测
     *
     * @param request [com.yonyougov.devops.cruxcisupport.backupuser.dto.IssuedTestRequestDto]
     * @return boolean
     */
    @Override
    public boolean issuedTestUsers(IssuedTestRequestDto request) {
        List<BigInteger> testUserIds = request.getTestUserIds();
        BigInteger commitTestId = request.getCommitTestId();
        String remark = request.getRemark();
        List<BackupTestUserEntity> backupTestUserEntityList = testUserIds.stream().map(testUserId -> {
            BackupTestUserEntity backupTestUserEntity = new BackupTestUserEntity();
            backupTestUserEntity.setId(new CruxDevOpsIdGenerator().generatorId(backupTestUserDao));
            backupTestUserEntity.setTestUserId(testUserId);
            backupTestUserEntity.setCommitTestId(commitTestId);
            backupTestUserEntity.setCreateTime(new Date());
            backupTestUserEntity.setRemark(remark);
            return backupTestUserEntity;
        }).collect(Collectors.toList());
        createCommitTrace(request);
        return backupTestUserDao.addBatch(backupTestUserEntityList);
    }

    /**
     * 查询提测单的测试人员
     * 条件: 提测单id
     *
     * @param commitTestId 提测单id
     * @return 测试人员昵称(多个使用逗号分割)
     */
    @Override
    public String findTestUserByCommitTestId(BigInteger commitTestId) {
        List<BackupUserVo> backupUserVoList = backupTestUserDao.getBackUserByCommitTestId(commitTestId);
        if (CollectionUtils.isEmpty(backupUserVoList)) {
            UserEntity leadUser = commitTestDao.findTestLeadByCommitTestId(CommitTestEntity.builder().id(commitTestId).build());
            return leadUser.getNickName();
        } else {
            return backupUserVoList.stream().map(BackupUserVo::getBackUpUserNickName).collect(Collectors.joining(","));
        }
    }

    /**
     * 检查身份为测试的用户是否具有操作提测单的权限
     *
     * @param processPermissionsDto com.yonyougov.devops.cruxcisupport.backupuser.dto.ProcessPermissionsDto
     * @return boolean
     */
    @Override
    public boolean processPermissions(ProcessPermissionsDto processPermissionsDto) {
        // 提测流程检查
        ArrayList<BigInteger> users = new ArrayList<>();
        CommitTestEntity query = commitTestDao.findBy(CommitTestEntity.builder().id(processPermissionsDto.getCommitTestId()).build());
        users.add(query.getTestLead());
        BackupTestUserEntity buildBackup = BackupTestUserEntity.builder().commitTestId(processPermissionsDto.getCommitTestId()).build();
        buildBackup.setPageAble(false);
        Pagination<BackupTestUserEntity> queryBackupUserList = backupTestUserService.findAllBy(buildBackup);
        users.addAll(queryBackupUserList.getDatas().stream().map(BackupTestUserEntity::getTestUserId).collect(Collectors.toList()));
        if (!users.contains(userService.getCurrentUser().getId())) return false;
        return true;
    }

    /**
     * 提测追踪入库
     *
     * @param request [com.yonyougov.devops.cruxcisupport.backupuser.dto.IssuedTestRequestDto]
     */
    private void createCommitTrace(IssuedTestRequestDto request) {
        CommitTraceEntity traceEntity = new CommitTraceEntity();
        traceEntity.setId(new CruxDevOpsIdGenerator().generatorId(commitTraceDao));
        traceEntity.setCreateTime(new Date());
        traceEntity.setCommitTestId(request.getCommitTestId());
        List<UserEntity> userEntityList = userDao.findByIds(new HashSet<>(request.getTestUserIds()));
        StringBuffer sb = new StringBuffer();
        userEntityList.forEach(u -> sb.append(u.getUserName()).append(","));
        traceEntity.setRemark(userStore.getCurrentUser().getUserName() + " 转测给 " + sb.substring(0, sb.length() - 1) + "  备注: " + request.getRemark());
        traceEntity.setStatus(TestStatusEnum.TRANSMIT_TEST.getValue());
        traceEntity.setOperatorId(userStore.getCurrentUser().getId());
        commitTraceDao.insert(traceEntity);


        Runnable r = () -> {
            CommitTestEntity commitTest = commitTestDao.get(request.getCommitTestId());
            Set<BigInteger> userIds = new HashSet<>();
            userIds.add(commitTest.getSubmitUserId());
            userIds.add(commitTest.getTestLead());
            userIds.addAll(new HashSet<>(request.getTestUserIds()));
            userIds.add(userStore.getCurrentUser().getId());
            //根据用户Id查询用户信息
            List<UserEntity> ul = userDao.findByIds(userIds);
            //获取邮箱列表
            String[] tos = ul.stream().map(UserEntity::getEmail).toArray(String[]::new);

            List<CommitContextInfoVo> contextInfoVos = commitContextService.
                    findCommitContextByCommitTestId(request.getCommitTestId());
            StringBuffer buffer = new StringBuffer();
            contextInfoVos.forEach(c -> buffer.append(c.getAppName()).append(",").
                    append(c.getVersionName()).append(",").append(c.getTestBranch()).append(";"));

            mailUtils.sendTextMail(FROM, tos, "【提测】转测 " + buffer.toString(),
                    userStore.getCurrentUser().getUserName() + "转测给" + sb.substring(0, sb.length() - 1) +
                            " 描述:" + request.getRemark());
        };
        new Thread(r).start();
    }
    //<!--用户自定义代码结束-->
}
